package cn.xuqiudong.console.config.sso;

import cn.xuqiudong.console.module.system.service.AuthorityService;
import cn.xuqiudong.sso.client.filter.LoginFilter;
import cn.xuqiudong.sso.client.filter.LogoutFilter;
import cn.xuqiudong.sso.client.listener.LogoutListener;
import cn.xuqiudong.sso.common.constant.SsoConstant;
import cn.xuqiudong.sso.common.model.RpcAccessToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.http.HttpSessionListener;
import java.util.function.Consumer;

/**
 * 描述:sso 配置
 * @author Vic.xu
 * @since 2022-09-21 17:15
 */
@Configuration
@EnableConfigurationProperties(CasSsoProperties.class)
public class CasSsoConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(CasSsoConfig.class);

    private AuthorityService authorityService;

    private CasSsoProperties casSsoProperties;

    public CasSsoConfig(AuthorityService authorityService, CasSsoProperties casSsoProperties) {
        this.authorityService = authorityService;
        this.casSsoProperties = casSsoProperties;
    }

    /**
     * 单实例方式单点登出Listener,因为它的存储策略就是LocalSessionMappingStorage， 所以无需额外设置
     *
     * @return LogoutListener
     */
    @Bean
    public ServletListenerRegistrationBean<HttpSessionListener> logoutListener() {
        ServletListenerRegistrationBean<HttpSessionListener> listenerRegBean = new ServletListenerRegistrationBean<>();
        LogoutListener logoutListener = new LogoutListener();
        listenerRegBean.setListener(logoutListener);
        return listenerRegBean;
    }

    /**
     * 登录过滤器
     *
     * @return FilterRegistrationBean<LoginFilter>
     */
    @Bean
    public FilterRegistrationBean<LoginFilter> loginFilter() {
        LoginFilter loginFilter = new LoginFilter();
        //前后端分离的登录过滤器
//        SeparationLoginFilter loginFilter = new SeparationLoginFilter(clientHost, htmlUrl);
        loginFilter.setAppId(casSsoProperties.getAppId());
        loginFilter.setAppSecret(casSsoProperties.getAppSecret());
        loginFilter.setServerUrl(casSsoProperties.getServerUrl());
        loginFilter.setGroup(casSsoProperties.getGroup());
        loginFilter.addExcludeUrl(SsoConstant.LOGOUT_URL);
        if (casSsoProperties.getExcludeUrls() != null) {
            casSsoProperties.getExcludeUrls().forEach(url -> loginFilter.addExcludeUrl(url));
        }
        //登录成功之后的回调
        Consumer<RpcAccessToken> afterLogin = accessToken -> {
            authorityService.afterLogin(accessToken.getUser().getId());
        };
        loginFilter.setAfterLogin(afterLogin);

        FilterRegistrationBean<LoginFilter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(loginFilter);
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.setOrder(2);
        filterRegistrationBean.setName("loginFilter");
        return filterRegistrationBean;
    }

    /**
     * 登出过滤器
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean<LogoutFilter> logoutFilter() {
        LogoutFilter logoutFilter = new LogoutFilter();
        logoutFilter.setAppId(casSsoProperties.getAppId());
        logoutFilter.setAppSecret(casSsoProperties.getAppSecret());
        logoutFilter.setServerUrl(casSsoProperties.getServerUrl());
        //登出成功后的回调
        logoutFilter.setAfterLogout(accessToken -> {
            // TODO
            LOGGER.info("logout success ; accessToken = {}", accessToken);
        });

        FilterRegistrationBean<LogoutFilter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(logoutFilter);
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.setOrder(1);
        filterRegistrationBean.setName("logoutFilter");
        return filterRegistrationBean;
    }


}
